'use strict';
const WebSocket = require('ws');
module.exports.run = function(d,s,req){
    const bs = require("../module/base"), gm = require("./game");
    switch(d[1]){
        case 1:{ //模拟用户
            if(!bs.checkParam(["acc","channelid","gametp"], d)) return;
            if(!isNaN(d[2].acc) || d[2].channelid != 1) return;

            bs.DB.query(`SELECT * FROM Users WHERE Account=$1`, (rs)=>{
                if(rs.rows.length) loginEnd(rs,d,s,req);
                else createUser(req, d, s);
            }, [d[2].acc])
            break;
        }case 2:{ //微信小游戏登录
            if(!bs.checkParam(["code","gametp"], d)) return;
            const https = require("https");
            let op = {
                host:"api.weixin.qq.com", 
                port:443, 
                path:"/sns/jscode2session?appid=wx064d5957f658a16e&secret=4e9a97cc335ced01be8a277b502e27ea&js_code=" + d[2].code + "&grant_type=authorization_code"
            };
            https.request(op, (res)=>{ //获取openid
                let cd = Buffer.allocUnsafe(0);
                res.on("data", (chunk)=>{
                    cd = Buffer.concat([cd, chunk], cd.length + chunk.length);
                });
                res.on("end", ()=>{
                    LOG.info(cd.toString());
                    let jn =  JSON.parse(cd.toString());

                    let session_key = "";
                    if(!jn.openid){
                        LOG.error("not openid");
                        return;
                    } 
                    d[2].acc = jn.openid;
                    session_key = jn.session_key;
                    //校验数据
                    const crypto = require("crypto");
                    let sh = crypto.createHash("sha1");
                    sh.update(d[2].rawData + session_key);
                    let shs = sh.digest('hex');
                    if(shs != d[2].signature){
                        LOG.error("sign", shs, d[2].signature);
                        return;
                    }
                    //获取解密数据
                    let cipher = crypto.createDecipheriv("aes-128-cbc", Buffer.from(session_key,"base64"), Buffer.from(d[2].iv,"base64"));
                    let ctxt = cipher.update(d[2].encryptedData, 'base64');
                    ctxt += cipher.final();
                    let uinfo = JSON.parse(ctxt);
                    LOG.info(ctxt);
                    if(uinfo.unionId) d[2].acc = uinfo.unionId;
                    //d[2].acc = jn.openid;
                    d[2].gender = uinfo.gender;
                    d[2].nickname = uinfo.nickName;
                    d[2].headimg = uinfo.avatarUrl;
                    d[2].channelid = 2;
                    LOG.info("mgame", JSON.stringify(d[2]));

                    //检查账号是否存在
                    bs.DB.query("SELECT * FROM Users WHERE Account=$1", (rs)=>{
                        if(rs.rows.length){
                            loginEnd(rs,d,s,req);
                        }else{
                            createUser(req, d, s);
                        }
                    }, [d[2].acc]);
                });
            }).end();
            break;
        }default:{
            LOG.error("not msg", d);
        }
    }
}

/** 登录完成 */
function loginEnd(rs, d, s, req){
    const bs = require("../module/base"), gm = require("./game");
    //检查是否已经网络关闭
    if(s.readyState != WebSocket.OPEN){
        LOG.error("net error", rs && rs.rows.length && rs.rows[0].userid || 0);
        return;
    }
    if(rs && rs.rows.length){
        if(d[2].password && d[2].password != rs.rows[0].password){
            return bs.sendE(s, 16);
        }
        s.U = {uid:rs.rows[0].userid, gametp:d[2].gametp, tm:Date.now()};
        //暂时限制单游戏登录
        if(s.U.uid in USERMAP){
            if(s.U.gametp == USERMAP[s.U.uid].U.gametp){
                s.U = USERMAP[s.U.uid].U;
            }
            USERMAP[s.U.uid].close();
        } 
        
        d[2] = rs.rows[0];
        gm.login(s);

        USERMAP[s.U.uid] = s;
        bs.DB.log("LoginLog", [s.U.uid,s.U.gametp,d[2].password,req.connection?req.connection.remoteAddress:"",d[2].channelid,'']);
    }else return bs.sendE(s, 3);
    bs.send(s, d);

    //记录在线玩家
    bs.RS(0).HSET("ONLINE:" + s.U.gametp, s.U.uid, Date.now());

    //检查是否有超时玩家
    let ct = Date.now();
    for(let k in USERMAP){
        if(!USERMAP[k].U.tm) USERMAP[k].U.tm = ct;
        else if(ct - USERMAP[k].U.tm > 6e5){
            if(USERMAP[k].readyState == WebSocket.CLOSED){
                let mod = require("./close");
                mod.run(null, USERMAP[k]);
            }else{
                bs.send(USERMAP[k], '[0,0]');
                USERMAP[k].U.tm = ct;
            }
        }
    }
}

/** 创建账号 */
function createUser(req, d, s){
    const bs = require("../module/base");
    bs.DB.query(`INSERT INTO Users(Account,password,nickname,headimg,gender,RegTime,LoginTime,LoginIP,ChannelID,MacNum) VALUES($1,$2,$3,$4,$5,NOW(),NOW(),$6,$7,'') RETURNING *`,(rs)=>{
        loginEnd(rs,d,s,req);
    }, [d[2].acc,d[2].password||"",d[2].nickname||"",d[2].headimg||"",d[2].gender||0,req.connection.remoteAddress,d[2].channelid]);
}